mod job_executor;
mod job_scheduler;
mod simple_job;
mod simple_scheduler;

pub use job_executor::*;
pub use job_scheduler::*;
pub use simple_job::*;
pub use simple_scheduler::*;

use std::borrow::BorrowMut;
use std::collections::HashMap;
use std::sync::{Arc, Mutex, RwLock};
use tokio::task::JoinHandle;

lazy_static::lazy_static! {
    pub(crate) static ref SCHEDULER: Arc<Mutex<SimpleScheduler>> = Arc::new(Mutex::new(SimpleScheduler::new()));

    pub(crate) static ref TICKER: RwLock<Option<JoinHandle<()>>> = RwLock::new(None);
}

pub fn simple_scheduler() -> Arc<Mutex<SimpleScheduler>> {
    SCHEDULER.clone()
}

pub(crate) fn start() -> anyhow::Result<()> {
    if TICKER
        .read()
        .map_err(|err| anyhow::anyhow!("{}", err))?
        .is_some()
    {
        return Ok(());
    } else {
        //
        let mut t = TICKER.write().map_err(|err| anyhow::anyhow!("{}", err))?;
        *t = Some(tokio::task::spawn(async move {
            loop {
                if let Ok(sched) = simple_scheduler()
                    .lock()
                    .map_err(|err| anyhow::anyhow!("{}", err))
                    .as_mut()
                {
                    sched.tick();
                    std::thread::sleep(sched.time_till_next_job());
                }
            }
        }));
    }
    Ok(())
}
